import gameClass.*;
import globals.*;
import screen.*;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.util.ArrayList;

import network.DataPackage;
import network.NetworkManager;

/**
 * @author Ben Elliott
 */
public class Game extends Canvas {
	/* For JPanel */
	private static final long serialVersionUID = 98765321320784L;
	
	/* Buffer */
	Image offscreen;
	Graphics offgc;
	
	private boolean loaded;
	
	public Game() {
		// Initialize
		Global.Instance().gameScreen = new GameScreen();
		Global.Instance().menuScreen = new MenuScreen();
		Global.Instance().loadScreen = new LoadScreen();
		Global.Instance().interfaceScreen = new InterfaceScreen();
		Global.Instance().loginScreen = new LoginScreen();
		
		// Set the starting screen of the game
		Global.Instance().currentScreen = ScreenType.Menu;
		
		// Create input manager
		Global.Instance().input = new InputManager();
		Global.Instance().camera = new Camera();
		Global.Instance().imgObs = this;
		Global.Instance().networkManager = new NetworkManager();
		Global.Instance().others = new ArrayList<DataPackage>();
		
		setFocusable( true );
		this.addKeyListener(Global.Instance().input);
		this.addMouseMotionListener(Global.Instance().input);
		this.addMouseListener(Global.Instance().input);
	}
	
	public void Load() {
		// Load fonts
		Fonts.title = new Font("Showcard Gothic", Font.BOLD, 64);
		Fonts.titleMetrics = getGraphics().getFontMetrics(Fonts.title);
		Fonts.menu = new Font("Arial", Font.BOLD, 16);
		Fonts.menuMetrics = getGraphics().getFontMetrics(Fonts.menu);
		
		// Load screens
		Global.Instance().menuScreen.Load();
		Global.Instance().interfaceScreen.Load();
		
		// Create the off-screen buffer
		offscreen = createImage(Global.Instance().winWidth, Global.Instance().winHeight);
		// Create the associated Graphics
		offgc = offscreen.getGraphics();
		
		loaded = true;
	}
	
	public void Update(float elapsed) {
		
		// Update the current screen
		switch (Global.Instance().currentScreen) {
			case Menu : Global.Instance().menuScreen.Update(elapsed); break;
			case Game : 
				if (Global.Instance().gameScreen.isLoaded()) {
					Global.Instance().interfaceScreen.Update(elapsed);
					Global.Instance().gameScreen.Update(elapsed);
				} else {
					// Lazy loading
					Global.Instance().gameScreen.Load();
					// Ensure update before draw
					Global.Instance().gameScreen.Update(0);  
				} break;
		}
		
		// Clear input last
		Global.Instance().input.clear();
	}
	
	public void update ( Graphics g )
	{
		paint(g);
	}
	
	public void paint(Graphics g) {
		
		if (!loaded) Load();
		
		// Clear the exposed area
		offgc.setColor(getBackground());
		offgc.fillRect(0, 0, Global.Instance().winWidth, Global.Instance().winHeight);
		offgc.setColor(getForeground());
		
		// Draw the current screen
		switch (Global.Instance().currentScreen) {
			case Menu : Global.Instance().menuScreen.Draw(offgc); break;
			case Game : 
				if (Global.Instance().gameScreen.isLoaded()) {
					Global.Instance().gameScreen.Draw(offgc);
					Global.Instance().interfaceScreen.Draw(offgc);
				} else
					Global.Instance().loadScreen.Draw(offgc);
				break;
		}
		
		// FPS for testing
		Font f = new Font("Arial", Font.BOLD, 20);
		offgc.setFont(f);
		offgc.setColor(Color.YELLOW);
		offgc.drawString("FPS: " + Global.Instance().fps, 10, 20);
        
		// transfer off-screen to window
		g.drawImage(offscreen, 0, 0, null);
	}


}
